"""
基础智能体类

定义所有智能体的基础接口和通用功能。
"""

from abc import ABC, abstractmethod
from typing import Dict, List, Any, Optional, Callable
from datetime import datetime
from dataclasses import dataclass, field
from enum import Enum
import uuid
import asyncio
from loguru import logger

from .agent_roles import AgentRole, AgentLevel, AgentRoleConfig, get_agent_config


class AgentStatus(Enum):
    """智能体状态"""
    IDLE = "idle"           # 空闲
    BUSY = "busy"           # 忙碌
    THINKING = "thinking"   # 思考中
    EXECUTING = "executing" # 执行中
    ERROR = "error"         # 错误状态
    OFFLINE = "offline"     # 离线


class TaskPriority(Enum):
    """任务优先级"""
    LOW = 1
    NORMAL = 2
    HIGH = 3
    URGENT = 4
    CRITICAL = 5


@dataclass
class Task:
    """任务定义"""
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    name: str = ""
    description: str = ""
    priority: TaskPriority = TaskPriority.NORMAL
    assigned_to: Optional[str] = None
    created_by: Optional[str] = None
    created_at: datetime = field(default_factory=datetime.now)
    deadline: Optional[datetime] = None
    status: str = "pending"
    data: Dict[str, Any] = field(default_factory=dict)
    result: Optional[Any] = None
    error: Optional[str] = None


@dataclass
class Message:
    """消息定义"""
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    sender: str = ""
    receiver: str = ""
    content: Any = None
    message_type: str = "info"
    timestamp: datetime = field(default_factory=datetime.now)
    metadata: Dict[str, Any] = field(default_factory=dict)


class BaseAgent(ABC):
    """基础智能体抽象类"""
    
    def __init__(
        self,
        agent_id: str,
        role: AgentRole,
        name: Optional[str] = None,
        description: Optional[str] = None,
        config: Optional[Dict[str, Any]] = None
    ):
        """
        初始化智能体
        
        Args:
            agent_id: 智能体唯一标识
            role: 智能体角色
            name: 智能体名称
            description: 智能体描述
            config: 智能体配置
        """
        self.agent_id = agent_id
        self.role = role
        self.role_config = get_agent_config(role)
        self.name = name or (self.role_config.name_zh if self.role_config else role.value)
        self.description = description or (self.role_config.description if self.role_config else "")
        self.config = config or {}
        
        # 状态管理
        self.status = AgentStatus.IDLE
        self.created_at = datetime.now()
        self.last_active = datetime.now()
        
        # 任务管理
        self.current_task: Optional[Task] = None
        self.task_queue: List[Task] = []
        self.completed_tasks: List[Task] = []
        
        # 消息管理
        self.message_queue: List[Message] = []
        self.message_handlers: Dict[str, Callable] = {}
        
        # 协作网络
        self.collaborators: List[str] = []
        self.managers: List[str] = []
        self.subordinates: List[str] = []
        
        # 性能指标
        self.metrics = {
            "tasks_completed": 0,
            "tasks_failed": 0,
            "average_response_time": 0.0,
            "success_rate": 0.0,
            "last_performance_update": datetime.now()
        }
        
        # 初始化协作关系
        self._initialize_collaboration()
        
        logger.info(f"智能体 {self.name} ({self.agent_id}) 初始化完成")
    
    def _initialize_collaboration(self):
        """初始化协作关系"""
        if not self.role_config:
            return
        
        # 设置管理关系
        self.managers = [role.value for role in self.role_config.reporting_to]
        self.subordinates = [role.value for role in self.role_config.manages]
        self.collaborators = [role.value for role in self.role_config.collaborates_with]
    
    @property
    def level(self) -> AgentLevel:
        """获取智能体层级"""
        return self.role_config.level if self.role_config else AgentLevel.OPERATIONAL
    
    @property
    def is_available(self) -> bool:
        """检查智能体是否可用"""
        return self.status in [AgentStatus.IDLE, AgentStatus.THINKING]
    
    @property
    def capabilities(self) -> List[str]:
        """获取智能体能力列表"""
        if not self.role_config:
            return []
        return [cap.name for cap in self.role_config.capabilities]
    
    async def start(self):
        """启动智能体"""
        self.status = AgentStatus.IDLE
        self.last_active = datetime.now()
        logger.info(f"智能体 {self.name} 已启动")
        
        # 启动消息处理循环
        asyncio.create_task(self._message_loop())
        asyncio.create_task(self._task_loop())
    
    async def stop(self):
        """停止智能体"""
        self.status = AgentStatus.OFFLINE
        logger.info(f"智能体 {self.name} 已停止")
    
    async def _message_loop(self):
        """消息处理循环"""
        while self.status != AgentStatus.OFFLINE:
            if self.message_queue:
                message = self.message_queue.pop(0)
                await self._handle_message(message)
            await asyncio.sleep(0.1)
    
    async def _task_loop(self):
        """任务处理循环"""
        while self.status != AgentStatus.OFFLINE:
            if self.is_available and self.task_queue:
                task = self.task_queue.pop(0)
                await self._execute_task(task)
            await asyncio.sleep(0.1)
    
    async def _handle_message(self, message: Message):
        """处理消息"""
        try:
            handler = self.message_handlers.get(message.message_type)
            if handler:
                await handler(message)
            else:
                await self.on_message_received(message)
        except Exception as e:
            logger.error(f"处理消息失败: {e}")
    
    async def _execute_task(self, task: Task):
        """执行任务"""
        try:
            self.current_task = task
            self.status = AgentStatus.EXECUTING
            task.status = "executing"
            
            start_time = datetime.now()
            
            # 执行具体任务
            result = await self.execute_task(task)
            
            # 更新任务状态
            task.result = result
            task.status = "completed"
            self.completed_tasks.append(task)
            
            # 更新性能指标
            execution_time = (datetime.now() - start_time).total_seconds()
            self._update_metrics(True, execution_time)
            
            logger.info(f"任务 {task.name} 执行完成")
            
        except Exception as e:
            task.error = str(e)
            task.status = "failed"
            self._update_metrics(False, 0)
            logger.error(f"任务 {task.name} 执行失败: {e}")
        
        finally:
            self.current_task = None
            self.status = AgentStatus.IDLE
            self.last_active = datetime.now()
    
    def _update_metrics(self, success: bool, execution_time: float):
        """更新性能指标"""
        if success:
            self.metrics["tasks_completed"] += 1
        else:
            self.metrics["tasks_failed"] += 1
        
        total_tasks = self.metrics["tasks_completed"] + self.metrics["tasks_failed"]
        self.metrics["success_rate"] = self.metrics["tasks_completed"] / total_tasks if total_tasks > 0 else 0
        
        # 更新平均响应时间
        if success and execution_time > 0:
            current_avg = self.metrics["average_response_time"]
            completed = self.metrics["tasks_completed"]
            self.metrics["average_response_time"] = (current_avg * (completed - 1) + execution_time) / completed
        
        self.metrics["last_performance_update"] = datetime.now()
    
    async def assign_task(self, task: Task) -> bool:
        """分配任务"""
        if not self.can_handle_task(task):
            return False
        
        task.assigned_to = self.agent_id
        
        # 根据优先级插入任务队列
        inserted = False
        for i, queued_task in enumerate(self.task_queue):
            if task.priority.value > queued_task.priority.value:
                self.task_queue.insert(i, task)
                inserted = True
                break
        
        if not inserted:
            self.task_queue.append(task)
        
        logger.info(f"任务 {task.name} 已分配给智能体 {self.name}")
        return True
    
    async def send_message(self, receiver: str, content: Any, message_type: str = "info"):
        """发送消息"""
        message = Message(
            sender=self.agent_id,
            receiver=receiver,
            content=content,
            message_type=message_type
        )
        
        # 这里应该通过消息总线发送消息
        # 暂时记录日志
        logger.info(f"智能体 {self.name} 向 {receiver} 发送消息: {message_type}")
        
        return message
    
    async def receive_message(self, message: Message):
        """接收消息"""
        self.message_queue.append(message)
    
    def register_message_handler(self, message_type: str, handler: Callable):
        """注册消息处理器"""
        self.message_handlers[message_type] = handler
    
    def get_status_info(self) -> Dict[str, Any]:
        """获取状态信息"""
        return {
            "agent_id": self.agent_id,
            "name": self.name,
            "role": self.role.value,
            "level": self.level.value,
            "status": self.status.value,
            "current_task": self.current_task.name if self.current_task else None,
            "queue_size": len(self.task_queue),
            "completed_tasks": len(self.completed_tasks),
            "metrics": self.metrics,
            "last_active": self.last_active.isoformat(),
            "capabilities": self.capabilities
        }
    
    # 抽象方法，子类必须实现
    @abstractmethod
    async def execute_task(self, task: Task) -> Any:
        """执行具体任务"""
        pass
    
    @abstractmethod
    def can_handle_task(self, task: Task) -> bool:
        """检查是否能处理指定任务"""
        pass
    
    # 可选重写的方法
    async def on_message_received(self, message: Message):
        """消息接收回调"""
        logger.info(f"智能体 {self.name} 收到消息: {message.message_type}")
    
    async def on_task_completed(self, task: Task):
        """任务完成回调"""
        logger.info(f"智能体 {self.name} 完成任务: {task.name}")
    
    async def on_error(self, error: Exception):
        """错误处理回调"""
        logger.error(f"智能体 {self.name} 发生错误: {error}")
        self.status = AgentStatus.ERROR